#
# mydbms/pysql_compiler/ast.py
#
"""
定义所有抽象语法树 (AST) 的节点类。
每个节点代表SQL查询中的一个语法结构。
"""
class ASTNode:
    """AST节点的基类"""
    def __repr__(self):
        # 通过__dict__动态生成节点的表示形式，方便调试
        fields = {k: v for k, v in self.__dict__.items() if not k.startswith('_')}
        return f"{self.__class__.__name__}({', '.join(f'{k}={v!r}' for k, v in fields.items())})"

# --- 字面量节点 ---
#存储一个value属性表示具体值。
#继承它的子类用于区分不同类型的字面量
class LiteralNode(ASTNode):
    def __init__(self, value):
        self.value = value

class NumberNode(LiteralNode): pass
class StringNode(LiteralNode): pass
class IdentifierNode(LiteralNode): pass
class StarNode(ASTNode): pass # 代表 SELECT * 中的 '*'
class DataTypeNode(LiteralNode): pass # 代表数据类型, e.g., INT, VARCHAR
class BooleanLiteralNode(LiteralNode): pass
# --- 表达式节点 ---
#用于表示二元运算或条件表达式（需要两个操作数的运算）
class BinaryOperationNode(ASTNode):
    """二元操作节点，例如: id = 10"""
    def __init__(self, left, op, right):
        self.left = left
        self.op = op
        self.right = right

class InPredicateNode(ASTNode):
    """IN 操作节点，例如: id IN (SELECT ...)"""
    def __init__(self, identifier, subquery):
        self.identifier = identifier
        self.subquery = subquery

class AssignmentNode(ASTNode):
    """赋值操作节点，例如: name = 'New Name'"""
    def __init__(self, column, value):
        self.column = column
        self.value = value

# <<<--- 为约束创建 AST 节点 (主键约束等) ---<<<
class ConstraintNode(ASTNode):
    """约束节点的基类"""
    pass

class PrimaryKeyConstraintNode(ConstraintNode): pass
class AutoIncrementConstraintNode(ConstraintNode): pass
class NotNullConstraintNode(ConstraintNode): pass
class UniqueConstraintNode(ConstraintNode):
    def __init__(self, columns: list[IdentifierNode] = None):
        self.columns = columns

class CheckConstraintNode(ConstraintNode):
    """CHECK 约束节点"""
    def __init__(self, expression):
        self.expression = expression

class ColumnDefinitionNode(ASTNode):
    """列定义节点，例如: id INT"""
    def __init__(self, column_name: IdentifierNode, data_type: DataTypeNode, constraints: list[ConstraintNode] = None):
        self.column_name = column_name
        self.data_type = data_type
        self.constraints = constraints or []

class OrderByNode(ASTNode):
    """ORDER BY 子句节点"""
    def __init__(self, column: IdentifierNode, order: str = 'ASC'):
        self.column = column
        self.order = order

# <<<--- 新增：为聚合函数和别名添加 AST 节点 ---<<<
class FunctionCallNode(ASTNode):
    """函数调用节点，例如: COUNT(age)"""
    def __init__(self, func_name: str, args: list):
        self.func_name = func_name
        self.args = args

class AliasNode(ASTNode):
    """别名节点，例如: COUNT(age) AS age_count"""
    def __init__(self, expression, alias: IdentifierNode):
        self.expression = expression
        self.alias = alias
# >>>--- 新增结束 ---<<<


# --- 新增JOIN节点 ---
class JoinNode(ASTNode):
    """JOIN 操作节点"""
    def __init__(self, left, right, join_type, condition):
        self.left = left
        self.right = right
        self.join_type = join_type # e.g., 'INNER', 'LEFT'
        self.condition = condition


# --- 语句节点 ---
class SelectStatementNode(ASTNode):
    """代表一个完整的 SELECT 查询"""
    def __init__(self, columns: list, from_clause, where_clause = None,
                 distinct: bool = False, order_by_clause: OrderByNode = None,
                 group_by_clause: list[IdentifierNode] = None, having_clause: BinaryOperationNode = None):
        self.columns = columns
        self.from_clause = from_clause
        self.where_clause = where_clause
        self.distinct = distinct
        self.order_by_clause = order_by_clause
        self.group_by_clause = group_by_clause
        self.having_clause = having_clause


class InsertStatementNode(ASTNode):
    """代表一个 INSERT 查询"""
    def __init__(self, table: IdentifierNode, columns: list[IdentifierNode], values: list[list[LiteralNode]]):
        self.table = table
        self.columns = columns
        self.values = values

class UpdateStatementNode(ASTNode):
    """代表一个 UPDATE 查询"""
    def __init__(self, table: IdentifierNode, assignments: list[AssignmentNode], from_table: IdentifierNode = None, where_clause: BinaryOperationNode = None):
        self.table = table
        self.assignments = assignments
        self.from_table = from_table
        self.where_clause = where_clause

class DeleteStatementNode(ASTNode):
    """代表一个 DELETE 查询"""
    def __init__(self, table: IdentifierNode, where_clause: BinaryOperationNode = None):
        self.table = table
        self.where_clause = where_clause

class CreateTableStatementNode(ASTNode):
    """代表一个 CREATE TABLE 查询"""
    def __init__(self, table_name: IdentifierNode, columns: list[ColumnDefinitionNode]):
        self.table_name = table_name
        self.columns = columns

# 为 CREATE INDEX 添加 AST 节点
class CreateIndexStatementNode(ASTNode):
    """代表一个 CREATE INDEX 查询"""
    def __init__(self, index_name: IdentifierNode, table_name: IdentifierNode, column_name: IdentifierNode):
        self.index_name = index_name
        self.table_name = table_name
        self.column_name = column_name

# <<<--- 新增：为 TRUNCATE TABLE 添加 AST 节点 ---<<<
class TruncateTableStatementNode(ASTNode):
    """代表一个 TRUNCATE TABLE 查询"""
    def __init__(self, table_name: IdentifierNode):
        self.table_name = table_name
# >>>--- 新增结束 ---<<<
class DropTableStatementNode(ASTNode):
    """代表一个 DROP TABLE 查询"""
    def __init__(self, table_name: IdentifierNode):
        self.table_name = table_name

class DropIndexStatementNode(ASTNode):
    """代表一个 DROP INDEX 查询"""
    def __init__(self, index_name: IdentifierNode):
        self.index_name = index_name
# <<<--- 为 ALTER TABLE 添加 AST 节点 ---<<<
class AlterTableStatementNode(ASTNode):
    """代表一个 ALTER TABLE 查询"""
    def __init__(self, table_name: IdentifierNode, action: ASTNode):
        self.table_name = table_name
        self.action = action

class AddColumnNode(ASTNode):
    """代表 ALTER TABLE ... ADD COLUMN ..."""
    def __init__(self, column_definition: ColumnDefinitionNode):
        self.column_definition = column_definition

class AlterColumnNode(ASTNode):
    """代表 ALTER TABLE ... ALTER COLUMN ..."""
    def __init__(self, column_name: IdentifierNode, new_data_type: DataTypeNode):
        self.column_name = column_name
        self.new_data_type = new_data_type

class DropColumnNode(ASTNode):
    """代表 ALTER TABLE ... DROP COLUMN ..."""
    def __init__(self, column_name: IdentifierNode):
        self.column_name = column_name

class AddPrimaryKeyNode(ASTNode):
    """代表 ALTER TABLE ... ADD PRIMARY KEY ..."""
    def __init__(self, column_name: IdentifierNode):
        self.column_name = column_name
# >>>--- ALTER结束 ---<<<
class UnaryOperationNode(ASTNode):
    """一元操作节点，例如: NOT condition"""
    def __init__(self, op, operand):
        self.op = op
        self.operand = operand

class LikePredicateNode(ASTNode):
    """LIKE 操作节点，例如: name LIKE '张%'"""
    def __init__(self, left, pattern):
        self.left = left
        self.pattern = pattern

class IsNullPredicateNode(ASTNode):
    """IS NULL 操作节点，例如: name IS NULL"""
    def __init__(self, left, is_not):
        self.left = left
        self.is_not = is_not # a boolean to handle IS NOT NULL

class ShowTablesStatementNode(ASTNode):
    """代表一个 SHOW TABLES 查询"""
    pass

# eg.SELECT name, age FROM users WHERE age > 18
# SelectStatementNode(
#     columns=[
#         IdentifierNode('name'),
#         IdentifierNode('age')
#     ],
#     table=IdentifierNode('users'),
#     where_clause=BinaryOperationNode(
#         left=IdentifierNode('age'),
#         op='>',
#         right=NumberNode(18)
#     )
# )

class ExplainStatementNode(ASTNode):
    """代表一个 EXPLAIN 查询"""
    def __init__(self, statement: ASTNode):
        self.statement = statement

class ForeignKeyConstraintNode(ConstraintNode):
    def __init__(self, column_name, ref_table, ref_column):
        self.column_name = column_name
        self.ref_table = ref_table
        self.ref_column = ref_column